package com.cheer.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;


/**
 * @author cheer
 */
@Component
@Slf4j
public class MatchListener implements ApplicationListener<ApplicationReadyEvent> {

    private static final Integer QUEUE_CAPACITY = 5000;

    private static PriorityBlockingQueue<MatchWebsocket> waitingQueue = new PriorityBlockingQueue<>(QUEUE_CAPACITY,
            Comparator.comparingInt(MatchWebsocket::getLevel));

    @Autowired
    private TaskExecutor taskExecutor;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        new Thread(() -> {
            while (true) {
                chooseOpponents();
            }
        }).start();
    }

    private void chooseOpponents() {
        try {
            MatchWebsocket firstUser = waitingQueue.take();
            MatchWebsocket secondUser = waitingQueue.poll(30, TimeUnit.SECONDS);

            if (secondUser == null) {
                taskExecutor.execute(firstUser::findNoOpponent);
                return;
            }

            taskExecutor.execute(() -> {
                firstUser.findOpponent(secondUser);
                secondUser.findOpponent(firstUser);
            });

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    public static boolean putUser(MatchWebsocket matchWebsocket) {
        if (waitingQueue.size() >= QUEUE_CAPACITY) {
            log.warn("匹配人数过多");
            return false;
        }
        waitingQueue.put(matchWebsocket);
        return true;
    }
}
